// OSR b ListGrepFiles
package org.jvcs.common;

import java.util.*;
import java.io.*;

import org.jvcs.common.*;

public final class ListGrepFiles {
  public static boolean sCase = true;
  public static String sExtn = null;
  public static String sDir = null;
  public static String sStr = null;
  
   
  public static void listgrep(File file) {
		String strFileName = file.getName();
		if (CmdLine.verboseFlag) osr.pl("=============================================================");
		if (CmdLine.verboseFlag) osr.pl("grep '"+sStr+"' "+strFileName+"=>"+file);			
		Utils.compile(sStr, sCase);
		Utils.grep(file);
		if (CmdLine.verboseFlag) osr.pl("FILE"+file);
		if (CmdLine.verboseFlag) osr.pl("=============================================================");
  }
  
  public static void launch() throws FileNotFoundException {
	if (CmdLine.verboseFlag) osr.pl("Launch begin");
	sDir = Utils.stdPath(sDir);
    File startingDirectory= new File(sDir);
	
    List<File> files = ListGrepFiles.getFileListing(startingDirectory);

    //print out all file names, in the the order of File.compareTo()
    for(File file : files ){
		boolean listgrepFlag = false;
		boolean exFlag = false;
		
		if (file.isFile()) {
			String strFileName = file.getName();
			// Step1: if ex is set, and inc is not set
			if (CmdLine.excludeFlag == true && CmdLine.includeFlag == false) {
				CmdLine.includeFlag = true;
				CmdLine.includeOptSet = "--include=*.*";
			}
			// Step2: if ex and inc both not set
			if (CmdLine.excludeFlag == false && CmdLine.includeFlag == false) {
				CmdLine.includeFlag = true;
				CmdLine.includeOptSet = "--include=*.*";
			}
			
			// Step3: if ex is set, collect the file exflag and pass to inc iteration
			if (CmdLine.excludeFlag) {
				if (CmdLine.verboseFlag) osr.pl("Exclude Flag ON");
				if ((CmdLine.excludeOptSet != null) && (CmdLine.isKV(CmdLine.excludeOptSet)) ) {
					 if (CmdLine.isSeq(CmdLine.excludeOptSet)) {					
						String [] inc = CmdLine.getSeq(CmdLine.excludeOptSet);
						for(String einc : inc) {
							if (CmdLine.verboseFlag) osr.pl("excludeList: "+einc);
							String regex = einc.replace("?", ".?").replace("*", ".*?");
							if (strFileName.matches(regex)) {
								if (CmdLine.verboseFlag) osr.pl("EXCLUDE CHECK :"+strFileName+" ==> "+regex);
								exFlag = true;
							} 
							
						}
					} else {
						String einc = CmdLine.getValue(CmdLine.excludeOptSet);
						if (CmdLine.verboseFlag) osr.pl("excludeOnly: "+einc);
						String regex = einc.replace("?", ".?").replace("*", ".*?");
						if (strFileName.matches(regex)) {
							if (CmdLine.verboseFlag) osr.pl("EXCLUDE CHECK :"+strFileName+" ==> "+regex);
							exFlag = true;
						} 
					}
				} 
			} 
			
			// Step4: finally check if inc is iterated, consider the ex flag and print, BTW exflag is false by default, allow all
			if (CmdLine.includeFlag) {
				if (CmdLine.verboseFlag) osr.pl("Include Flag ON");
				if ((CmdLine.includeOptSet != null) && (CmdLine.isKV(CmdLine.includeOptSet)) ) {
					 if (CmdLine.isSeq(CmdLine.includeOptSet)) {					
						String [] inc = CmdLine.getSeq(CmdLine.includeOptSet);
						for(String einc : inc) {
							if (CmdLine.verboseFlag) osr.pl("includeList: "+einc);
							String regex = einc.replace("?", ".?").replace("*", ".*?");
							if (strFileName.matches(regex)) {
								if (exFlag == false)
									listgrep(file);
							}							
						}
					} else {
						String einc = CmdLine.getValue(CmdLine.includeOptSet);
						if (CmdLine.verboseFlag) osr.pl("includeOnly: "+einc);
						String regex = einc.replace("?", ".?").replace("*", ".*?");
						if (strFileName.matches(regex)) {
							if (exFlag == false)
								listgrep(file);
						}	
					}
				} 
			} 
			
			
			
		}
    }
  }
 
  static public List<File> getFileListing(
    File aStartingDir
  ) throws FileNotFoundException {
    validateDirectory(aStartingDir);
    List<File> result = getFileListingNoSort(aStartingDir);
    Collections.sort(result);
    return result;
  }

  // PRIVATE //
  static private List<File> getFileListingNoSort(
    File aStartingDir
  ) throws FileNotFoundException {
    List<File> result = new ArrayList<File>();
	File[] filesAndDirs = aStartingDir.listFiles();
	List<File> filesDirs = Arrays.asList(filesAndDirs);
    for(File file : filesDirs) {
      result.add(file); //always add, even if directory
      if ( ! file.isFile() ) {
        //must be a directory
        //recursive call!
        List<File> deeperList = getFileListingNoSort(file);
        result.addAll(deeperList);
      }
    }
    return result;
  }

 
  static private void validateDirectory (
    File aDirectory
  ) throws FileNotFoundException {
    if (aDirectory == null) {
      throw new IllegalArgumentException("Directory should not be null.");
    }
    if (!aDirectory.exists()) {
      throw new FileNotFoundException("Directory does not exist: " + aDirectory);
    }
    if (!aDirectory.isDirectory()) {
      throw new IllegalArgumentException("Is not a directory: " + aDirectory);
    }
    if (!aDirectory.canRead()) {
      throw new IllegalArgumentException("Directory cannot be read: " + aDirectory);
    }
  }
} 
